home *** CD-ROM | disk | FTP | other *** search
/ HPAVC / HPAVC CD-ROM.iso / MOR55SRC.ZIP / MORIA / SOURCE / RECALL.C < prev    next >
C/C++ Source or Header  |  1992-12-07  |  17KB  |  753 lines

  1. /* source/recall.c: print out monster memory info            -CJS-
  2.  
  3.    Copyright (c) 1989-92 James E. Wilson, Christopher J. Stuart
  4.  
  5.    This software may be copied and distributed for educational, research, and
  6.    not for profit purposes provided that this copyright and statement are
  7.    included in all such copies. */
  8.  
  9. #ifdef __TURBOC__
  10. #include    <stdio.h>
  11. #endif /* __TURBOC__ */
  12.  
  13. #include "config.h"
  14. #include "constant.h"
  15. #include "types.h"
  16. #include "externs.h"
  17.  
  18. #if defined(LINT_ARGS)
  19. static void roff(char *);
  20. #else
  21. static void roff();
  22. #endif
  23.  
  24. static char *desc_atype[] = {
  25.   "do something undefined",
  26.   "attack",
  27.   "weaken",
  28.   "confuse",
  29.   "terrify",
  30.   "shoot flames",
  31.   "shoot acid",
  32.   "freeze",
  33.   "shoot lightning",
  34.   "corrode",
  35.   "blind",
  36.   "paralyse",
  37.   "steal money",
  38.   "steal things",
  39.   "poison",
  40.   "reduce dexterity",
  41.   "reduce constitution",
  42.   "drain intelligence",
  43.   "drain wisdom",
  44.   "lower experience",
  45.   "call for help",
  46.   "disenchant",
  47.   "eat your food",
  48.   "absorb light",
  49.   "absorb charges" };
  50. static char *desc_amethod[] = {
  51.   "make an undefined advance",
  52.   "hit",
  53.   "bite",
  54.   "claw",
  55.   "sting",
  56.   "touch",
  57.   "kick",
  58.   "gaze",
  59.   "breathe",
  60.   "spit",
  61.   "wail",
  62.   "embrace",
  63.   "crawl on you",
  64.   "release spores",
  65.   "beg",
  66.   "slime you",
  67.   "crush",
  68.   "trample",
  69.   "drool",
  70.   "insult" };
  71. static char *desc_howmuch[] = {
  72.   " not at all",
  73.   " a bit",
  74.   "",
  75.   " quite",
  76.   " very",
  77.   " most",
  78.   " highly",
  79.   " extremely" };
  80.  
  81. static char *desc_move[] = {
  82.   "move invisibly",
  83.   "open doors",
  84.   "pass through walls",
  85.   "kill weaker creatures",
  86.   "pick up objects",
  87.   "breed explosively" };
  88. static char *desc_spell[] = {
  89.   "teleport short distances",
  90.   "teleport long distances",
  91.   "teleport its prey",
  92.   "cause light wounds",
  93.   "cause serious wounds",
  94.   "paralyse its prey",
  95.   "induce blindness",
  96.   "confuse",
  97.   "terrify",
  98.   "summon a monster",
  99.   "summon the undead",
  100.   "slow its prey",
  101.   "drain mana",
  102.   "unknown 1",
  103.   "unknown 2" };
  104. static char *desc_breath[] = {
  105.   "lightning",
  106.   "poison gases",
  107.   "acid",
  108.   "frost",
  109.   "fire" };
  110. static char *desc_weakness[] = {
  111.   "frost",
  112.   "fire",
  113.   "poison",
  114.   "acid",
  115.   "bright light",
  116.   "rock remover" };
  117.  
  118. static vtype roffbuf;        /* Line buffer. */
  119. static char *roffp;        /* Pointer into line buffer. */
  120. static int roffpline;        /* Place to print line now being loaded. */
  121.  
  122. #define plural(c, ss, sp)    ((c) == 1 ? ss : sp)
  123.  
  124. /* Number of kills needed for information. */
  125.  
  126. /* the higher the level of the monster, the fewer the kills you need */
  127. #define knowarmor(l,d)        ((d) > 304 / (4 + (l)))
  128. /* the higher the level of the monster, the fewer the attacks you need,
  129.    the more damage an attack does, the more attacks you need */
  130. #define knowdamage(l,a,d)    ((4 + (l))*(a) > 80 * (d))
  131.  
  132. /* Do we know anything about this monster? */
  133. int bool_roff_recall(mon_num)
  134. int mon_num;
  135. {
  136.   register recall_type *mp;
  137.   register int i;
  138.  
  139.   if (wizard)
  140.     return TRUE;
  141.   mp = &c_recall[mon_num];
  142.   if (mp->r_cmove || mp->r_cdefense || mp->r_kills || mp->r_spells
  143.       || mp->r_deaths)
  144.     return TRUE;
  145.   for (i = 0; i < 4; i++)
  146.     if (mp->r_attacks[i])
  147.       return TRUE;
  148.   return FALSE;
  149. }
  150.  
  151. /* Print out what we have discovered about this monster. */
  152. int roff_recall(mon_num)
  153. int mon_num;
  154. {
  155.   char *p, *q;
  156.   int8u *pu;
  157.   vtype temp;
  158.   register recall_type *mp;
  159.   register creature_type *cp;
  160.   register int i, k;
  161.   register int32u j;
  162.   int32 templong;
  163.   int mspeed;
  164.   int32u rcmove, rspells;
  165.   int16u rcdefense;
  166.   recall_type save_mem;
  167. #ifdef ATARIST_MWC
  168.   int32u holder;
  169.   int32u holder2;
  170. #endif
  171.  
  172.   mp = &c_recall[mon_num];
  173.   cp = &c_list[mon_num];
  174.   if (wizard)
  175.     {
  176.       save_mem = *mp;
  177.       mp->r_kills = MAX_SHORT;
  178.       mp->r_wake = mp->r_ignore = MAX_UCHAR;
  179. #ifdef ATARIST_MWC
  180.       j = (((cp->cmove & (holder = CM_4D2_OBJ)) != 0) * 8) +
  181.     (((cp->cmove & (holder = CM_2D2_OBJ)) != 0) * 4) +
  182.       (((cp->cmove & (holder = CM_1D2_OBJ)) != 0) * 2) +
  183.         ((cp->cmove & (holder = CM_90_RANDOM)) != 0) +
  184.           ((cp->cmove & (holder = CM_60_RANDOM)) != 0);
  185.       holder = CM_TREASURE;
  186.       mp->r_cmove = (cp->cmove & ~holder) | (j << CM_TR_SHIFT);
  187. #else
  188.       j = (((cp->cmove & CM_4D2_OBJ) != 0) * 8) +
  189.     (((cp->cmove & CM_2D2_OBJ) != 0) * 4) +
  190.       (((cp->cmove & CM_1D2_OBJ) != 0) * 2) +
  191.         ((cp->cmove & CM_90_RANDOM) != 0) +
  192.           ((cp->cmove & CM_60_RANDOM) != 0);
  193.       mp->r_cmove = (cp->cmove & ~CM_TREASURE) | (j << CM_TR_SHIFT);
  194. #endif
  195.       mp->r_cdefense = cp->cdefense;
  196.       mp->r_spells = cp->spells | CS_FREQ;
  197.       j = 0;
  198.       pu = cp->damage;
  199.       while (*pu != 0 && j < 4)
  200.     {
  201.       /* Turbo C needs a 16 bit int for the array index.  */
  202.       mp->r_attacks[(int)j] = MAX_UCHAR;
  203.       j++;
  204.       pu++;
  205.     }
  206.       /* A little hack to enable the display of info for Quylthulgs.  */
  207.       if (mp->r_cmove & CM_ONLY_MAGIC)
  208.     mp->r_attacks[0] = MAX_UCHAR;
  209.     }
  210.   roffpline = 0;
  211.   roffp = roffbuf;
  212. #ifdef ATARIST_MWC
  213.   holder = ~CS_FREQ;
  214.   rspells = mp->r_spells & cp->spells & holder;
  215.   /* the CM_WIN property is always known, set it if a win monster */
  216.   holder = CM_WIN;
  217.   rcmove = mp->r_cmove | (holder & cp->cmove);
  218. #else
  219.   rspells = mp->r_spells & cp->spells & ~CS_FREQ;
  220.   /* the CM_WIN property is always known, set it if a win monster */
  221.   rcmove = mp->r_cmove | (CM_WIN & cp->cmove);
  222. #endif
  223.   rcdefense = mp->r_cdefense & cp->cdefense;
  224.   (void) sprintf(temp, "The %s:\n", cp->name);
  225.   roff(temp);
  226.   /* Conflict history. */
  227.   if(mp->r_deaths)
  228.     {
  229.       (void) sprintf(temp,
  230.              "%d of the contributors to your monster memory %s",
  231.              mp->r_deaths, plural(mp->r_deaths, "has", "have") );
  232.       roff(temp);
  233.       roff(" been killed by this creature, and ");
  234.       if (mp->r_kills == 0)
  235.     roff("it is not ever known to have been defeated.");
  236.       else
  237.     {
  238.       (void) sprintf(temp,
  239.              "at least %d of the beasts %s been exterminated.",
  240.              mp->r_kills, plural(mp->r_kills, "has", "have") );
  241.       roff(temp);
  242.     }
  243.     }
  244.   else if (mp->r_kills)
  245.     {
  246.       (void) sprintf(temp, "At least %d of these creatures %s",
  247.              mp->r_kills, plural(mp->r_kills, "has", "have") );
  248.       roff(temp);
  249.       roff(" been killed by contributors to your monster memory.");
  250.     }
  251.   else
  252.     roff("No known battles to the death are recalled.");
  253.   /* Immediately obvious. */
  254.   k = FALSE;
  255.   if (cp->level == 0)
  256.     {
  257.       roff(" It lives in the town");
  258.       k = TRUE;
  259.     }
  260.   else if (mp->r_kills)
  261.     {
  262.       /* The Balrog is a level 100 monster, but appears at 50 feet.  */
  263.       i = cp->level;
  264.       if (i > WIN_MON_APPEAR)
  265.     i = WIN_MON_APPEAR;
  266.       (void) sprintf(temp, " It is normally found at depths of %d feet",
  267.              i * 50);
  268.       roff(temp);
  269.       k = TRUE;
  270.     }
  271.   /* the c_list speed value is 10 greater, so that it can be a int8u */
  272.   mspeed = cp->speed - 10;
  273.   if (rcmove & CM_ALL_MV_FLAGS)
  274.     {
  275.       if (k)
  276.     roff(", and");
  277.       else
  278.     {
  279.       roff(" It");
  280.       k = TRUE;
  281.     }
  282.       roff(" moves");
  283.       if (rcmove & CM_RANDOM_MOVE)
  284.     {
  285.       /* Turbo C needs a 16 bit int for the array index.  */
  286.       roff(desc_howmuch[(int)((rcmove & CM_RANDOM_MOVE) >> 3)]);
  287.       roff(" erratically");
  288.     }
  289.       if (mspeed == 1)
  290.     roff(" at normal speed");
  291.       else
  292.     {
  293.       if (rcmove & CM_RANDOM_MOVE)
  294.         roff(", and");
  295.       if (mspeed <= 0)
  296.         {
  297.           if (mspeed == -1)
  298.         roff(" very");
  299.           else if (mspeed < -1)
  300.         roff(" incredibly");
  301.           roff(" slowly");
  302.         }
  303.       else
  304.         {
  305.           if (mspeed == 3)
  306.         roff(" very");
  307.           else if (mspeed > 3)
  308.         roff(" unbelievably");
  309.           roff(" quickly");
  310.         }
  311.     }
  312.     }
  313.   if (rcmove & CM_ATTACK_ONLY)
  314.     {
  315.       if(k)
  316.     roff(", but");
  317.       else
  318.     {
  319.       roff(" It");
  320.       k = TRUE;
  321.     }
  322.       roff(" does not deign to chase intruders");
  323.     }
  324.   if (rcmove & CM_ONLY_MAGIC)
  325.     {
  326.       if (k)
  327.     roff (", but");
  328.       else
  329.     {
  330.       roff (" It");
  331.       k = TRUE;
  332.     }
  333.       roff (" always moves and attacks by using magic");
  334.     }
  335.   if(k)
  336.     roff(".");
  337.   /* Kill it once to know experience, and quality (evil, undead, monsterous).
  338.      The quality of being a dragon is obvious. */
  339.   if (mp->r_kills)
  340.     {
  341.       roff(" A kill of this");
  342.       if (cp->cdefense & CD_ANIMAL)
  343.     roff(" natural");
  344.       if (cp->cdefense & CD_EVIL)
  345.     roff(" evil");
  346.       if (cp->cdefense & CD_UNDEAD)
  347.     roff(" undead");
  348.  
  349.       /* calculate the integer exp part, can be larger than 64K when first
  350.      level character looks at Balrog info, so must store in long */
  351.       templong = (long)cp->mexp * cp->level / py.misc.lev;
  352.       /* calculate the fractional exp part scaled by 100,
  353.      must use long arithmetic to avoid overflow */
  354.       j = (((long)cp->mexp * cp->level % py.misc.lev) * (long)1000 /
  355.        py.misc.lev+5) / 10;
  356.  
  357.       (void) sprintf(temp, " creature is worth %ld.%02ld point%s", templong,
  358.              j, (templong == 1 && j == 0 ? "" : "s"));
  359.       roff(temp);
  360.  
  361.       if (py.misc.lev / 10 == 1) p = "th";
  362.       else
  363.     {
  364.       i = py.misc.lev % 10;
  365.       if (i == 1)        p = "st";
  366.       else if (i == 2)    p = "nd";
  367.       else if (i == 3)      p = "rd";
  368.       else            p = "th";
  369.     }
  370.       i = py.misc.lev;
  371.       if (i == 8 || i == 11 || i == 18) q = "n";
  372.       else                q = "";
  373.       (void) sprintf(temp, " for a%s %d%s level character.", q, i, p);
  374.       roff(temp);
  375.     }
  376.   /* Spells known, if have been used against us. */
  377.   k = TRUE;
  378.   j = rspells;
  379. #ifdef ATARIST_MWC
  380.   holder = CS_BREATHE;
  381.   holder2 = CS_BR_LIGHT;
  382.   for (i = 0; j & holder; i++)
  383. #else
  384.   for (i = 0; j & CS_BREATHE; i++)
  385. #endif
  386.     {
  387. #ifdef ATARIST_MWC
  388.       if (j & (holder2 << i))
  389. #else
  390.       if (j & (CS_BR_LIGHT << i))
  391. #endif
  392.     {
  393. #ifdef ATARIST_MWC
  394.       j &= ~(holder2 << i);
  395. #else
  396.       j &= ~(CS_BR_LIGHT << i);
  397. #endif
  398.       if (k)
  399.         {
  400.           roff(" It can breathe ");
  401.           k = FALSE;
  402.         }
  403. #ifdef ATARIST_MWC
  404.       else if (j & holder)
  405. #else
  406.       else if (j & CS_BREATHE)
  407. #endif
  408.         roff(", ");
  409.       else
  410.         roff(" and ");
  411.       roff(desc_breath[i]);
  412.     }
  413.     }
  414.   k = TRUE;
  415. #ifdef ATARIST_MWC
  416.   holder = CS_SPELLS;
  417.   for (i = 0; j & holder; i++)
  418. #else
  419.   for (i = 0; j & CS_SPELLS; i++)
  420. #endif
  421.     {
  422.       if (j & (CS_TEL_SHORT << i))
  423.     {
  424.       j &= ~(CS_TEL_SHORT << i);
  425.       if (k)
  426.         {
  427. #ifdef ATARIST_MWC
  428.           holder2 = CS_BREATHE;
  429.           if (rspells & holder2)
  430. #else
  431.           if (rspells & CS_BREATHE)
  432. #endif
  433.         roff(", and is also");
  434.           else
  435.         roff(" It is");
  436.           roff(" magical, casting spells which ");
  437.           k = FALSE;
  438.         }
  439. #ifdef ATARIST_MWC
  440.       else if (j & holder)
  441. #else
  442.       else if (j & CS_SPELLS)
  443. #endif
  444.         roff(", ");
  445.       else
  446.         roff(" or ");
  447.       roff(desc_spell[i]);
  448.     }
  449.     }
  450. #ifdef ATARIST_MWC
  451.   holder = CS_BREATHE|CS_SPELLS;
  452.   if (rspells & holder)
  453. #else
  454.   if (rspells & (CS_BREATHE|CS_SPELLS))
  455. #endif
  456.     {
  457.       if ((mp->r_spells & CS_FREQ) > 5)
  458.     {    /* Could offset by level */
  459.       (void) sprintf(temp, "; 1 time in %ld", cp->spells & CS_FREQ);
  460.       roff(temp);
  461.     }
  462.       roff(".");
  463.     }
  464.   /* Do we know how hard they are to kill? Armor class, hit die. */
  465.   if (knowarmor(cp->level, mp->r_kills))
  466.     {
  467.       (void) sprintf(temp, " It has an armor rating of %d", cp->ac);
  468.       roff(temp);
  469.       (void) sprintf(temp, " and a%s life rating of %dd%d.",
  470.              ((cp->cdefense & CD_MAX_HP) ? " maximized" : ""),
  471.              cp->hd[0], cp->hd[1]);
  472.       roff(temp);
  473.     }
  474.   /* Do we know how clever they are? Special abilities. */
  475.   k = TRUE;
  476.   j = rcmove;
  477. #ifdef ATARIST_MWC
  478.   holder = CM_SPECIAL;
  479.   holder2 = CM_INVISIBLE;
  480.   for (i = 0; j & holder; i++)
  481. #else
  482.   for (i = 0; j & CM_SPECIAL; i++)
  483. #endif
  484.     {
  485. #ifdef ATARIST_MWC
  486.       if (j & (holder2 << i))
  487. #else
  488.       if (j & (CM_INVISIBLE << i))
  489. #endif
  490.     {
  491. #ifdef ATARIST_MWC
  492.       j &= ~(holder2 << i);
  493. #else
  494.       j &= ~(CM_INVISIBLE << i);
  495. #endif
  496.       if (k)
  497.         {
  498.           roff(" It can ");
  499.           k = FALSE;
  500.         }
  501. #ifdef ATARIST_MWC
  502.       else if (j & holder)
  503. #else
  504.       else if (j & CM_SPECIAL)
  505. #endif
  506.         roff(", ");
  507.       else
  508.         roff(" and ");
  509.       roff(desc_move[i]);
  510.     }
  511.     }
  512.   if (!k)
  513.     roff(".");
  514.   /* Do we know its special weaknesses? Most cdefense flags. */
  515.   k = TRUE;
  516.   j = rcdefense;
  517.   for (i = 0; j & CD_WEAKNESS; i++)
  518.     {
  519.       if (j & (CD_FROST << i))
  520.     {
  521.       j &= ~(CD_FROST << i);
  522.       if (k)
  523.         {
  524.           roff(" It is susceptible to ");
  525.           k = FALSE;
  526.         }
  527.       else if (j & CD_WEAKNESS)
  528.         roff(", ");
  529.       else
  530.         roff(" and ");
  531.       roff(desc_weakness[i]);
  532.     }
  533.     }
  534.   if (!k)
  535.     roff(".");
  536.   if (rcdefense & CD_INFRA)
  537.     roff(" It is warm blooded");
  538.   if (rcdefense & CD_NO_SLEEP)
  539.     {
  540.       if (rcdefense & CD_INFRA)
  541.     roff(", and");
  542.       else
  543.     roff(" It");
  544.       roff(" cannot be charmed or slept");
  545.     }
  546.   if (rcdefense & (CD_NO_SLEEP|CD_INFRA))
  547.     roff(".");
  548.   /* Do we know how aware it is? */
  549.   if (((mp->r_wake * mp->r_wake) > cp->sleep) || mp->r_ignore == MAX_UCHAR ||
  550.       (cp->sleep == 0 && mp->r_kills >= 10))
  551.     {
  552.       roff(" It ");
  553.       if(cp->sleep > 200)
  554.     roff("prefers to ignore");
  555.       else if(cp->sleep > 95)
  556.     roff("pays very little attention to");
  557.       else if(cp->sleep > 75)
  558.     roff("pays little attention to");
  559.       else if(cp->sleep > 45)
  560.     roff("tends to overlook");
  561.       else if(cp->sleep > 25)
  562.     roff("takes quite a while to see");
  563.       else if(cp->sleep > 10)
  564.     roff("takes a while to see");
  565.       else if(cp->sleep > 5)
  566.     roff("is fairly observant of");
  567.       else if(cp->sleep > 3)
  568.     roff("is observant of");
  569.       else if(cp->sleep > 1)
  570.     roff("is very observant of");
  571.       else if(cp->sleep != 0)
  572.     roff("is vigilant for");
  573.       else
  574.     roff("is ever vigilant for");
  575.       (void) sprintf(temp, " intruders, which it may notice from %d feet.",
  576.              10 * cp->aaf);
  577.       roff(temp);
  578.     }
  579.   /* Do we know what it might carry? */
  580. #ifdef ATARIST_MWC
  581.   holder = CM_CARRY_OBJ|CM_CARRY_BOLD;
  582.   if (rcmove & holder)
  583. #else
  584.   if (rcmove & (CM_CARRY_OBJ|CM_CARRY_GOLD))
  585. #endif
  586.     {
  587.       roff(" It may");
  588. #ifdef ATARIST_MWC
  589.       j = (rcmove & (holder = CM_TREASURE)) >> CM_TR_SHIFT;
  590. #else
  591.       j = (rcmove & CM_TREASURE) >> CM_TR_SHIFT;
  592. #endif
  593.       if (j == 1)
  594.     {
  595. #ifdef ATARIST_MWC
  596.       if ((cp->cmove & (holder = CM_TREASURE)) == CM_60_RANDOM)
  597. #else
  598.       if ((cp->cmove & CM_TREASURE) == CM_60_RANDOM)
  599. #endif
  600.         roff(" sometimes");
  601.       else
  602.         roff(" often");
  603.     }
  604. #ifdef ATARIST_MWC
  605.       else if ((j == 2) && ((cp->cmove & (holder = CM_TREASURE)) ==
  606. #else
  607.       else if ((j == 2) && ((cp->cmove & CM_TREASURE) ==
  608. #endif
  609.                 (CM_60_RANDOM|CM_90_RANDOM)))
  610.     roff (" often");
  611.       roff(" carry");
  612.       p = " objects";
  613.       if (j == 1)
  614.     p = " an object";
  615.       else if (j == 2)
  616.     roff(" one or two");
  617.       else
  618.     {
  619.       (void) sprintf(temp, " up to %ld", j);
  620.       roff(temp);
  621.     }
  622. #ifdef ATARIST_MWC
  623.       if (rcmove & (holder = CM_CARRY_OBJ))
  624. #else
  625.       if (rcmove & CM_CARRY_OBJ)
  626. #endif
  627.     {
  628.       roff(p);
  629. #ifdef ATARIST_MWC
  630.       if (rcmove & (holder = CM_CARRY_GOLD))
  631. #else
  632.       if (rcmove & CM_CARRY_GOLD)
  633. #endif
  634.         {
  635.           roff(" or treasure");
  636.           if (j > 1)
  637.         roff("s");
  638.         }
  639.       roff(".");
  640.     }
  641.       else if (j != 1)
  642.     roff(" treasures.");
  643.       else
  644.     roff(" treasure.");
  645.     }
  646.  
  647.   /* We know about attacks it has used on us, and maybe the damage they do. */
  648.   /* k is the total number of known attacks, used for punctuation */
  649.   k = 0;
  650.   for (j = 0; j < 4; j++)
  651.     /* Turbo C needs a 16 bit int for the array index.  */
  652.     if (mp->r_attacks[(int)j])
  653.       k++;
  654.   pu = cp->damage;
  655.   /* j counts the attacks as printed, used for punctuation */
  656.   j = 0;
  657.   for (i = 0; *pu != 0 && i < 4; pu++, i++)
  658.     {
  659.       int att_type, att_how, d1, d2;
  660.  
  661.       /* don't print out unknown attacks */
  662.       if (!mp->r_attacks[i])
  663.     continue;
  664.  
  665.       att_type = monster_attacks[*pu].attack_type;
  666.       att_how = monster_attacks[*pu].attack_desc;
  667.       d1 = monster_attacks[*pu].attack_dice;
  668.       d2 = monster_attacks[*pu].attack_sides;
  669.  
  670.       j++;
  671.       if (j == 1)
  672.     roff(" It can ");
  673.       else if (j == k)
  674.     roff(", and ");
  675.       else
  676.     roff(", ");
  677.  
  678.       if (att_how > 19)
  679.     att_how = 0;
  680.       roff(desc_amethod[att_how]);
  681.       if (att_type != 1 || d1 > 0 && d2 > 0)
  682.     {
  683.       roff(" to ");
  684.       if (att_type > 24)
  685.         att_type = 0;
  686.       roff(desc_atype[att_type]);
  687.       if (d1 && d2)
  688.         {
  689.           if (knowdamage(cp->level, mp->r_attacks[i], d1*d2))
  690.         {
  691.           if (att_type == 19)    /* Loss of experience */
  692.             roff(" by");
  693.           else
  694.             roff(" with damage");
  695.           (void) sprintf(temp, " %dd%d", d1, d2 );
  696.           roff(temp);
  697.         }
  698.         }
  699.     }
  700.     }
  701.   if (j)
  702.     roff(".");
  703.   else if (k > 0 && mp->r_attacks[0] >= 10)
  704.     roff(" It has no physical attacks.");
  705.   else
  706.     roff(" Nothing is known about its attack.");
  707.   /* Always know the win creature. */
  708. #ifdef ATARIST_MWC
  709.   if (cp->cmove & (holder = CM_WIN))
  710. #else
  711.   if (cp->cmove & CM_WIN)
  712. #endif
  713.     roff(" Killing one of these wins the game!");
  714.   roff("\n");
  715.   prt("--pause--", roffpline, 0);
  716.   if (wizard)
  717.     *mp = save_mem;
  718.   return inkey();
  719. }
  720.  
  721. /* Print out strings, filling up lines as we go. */
  722. static void roff(p)
  723. register char *p;
  724. {
  725.   register char *q, *r;
  726.  
  727.   while (*p)
  728.     {
  729.       *roffp = *p;
  730.       if (*p == '\n' || roffp >= roffbuf + sizeof(roffbuf)-1)
  731.     {
  732.       q = roffp;
  733.       if (*p != '\n')
  734.         while (*q != ' ')
  735.           q--;
  736.       *q = 0;
  737.       prt(roffbuf, roffpline, 0);
  738.       roffpline++;
  739.       r = roffbuf;
  740.       while (q < roffp)
  741.         {
  742.           q++;
  743.           *r = *q;
  744.           r++;
  745.         }
  746.       roffp = r;
  747.     }
  748.       else
  749.     roffp++;
  750.       p++;
  751.     }
  752. }
  753.